import type { App, DirectiveBinding } from 'vue'
import { getPlaid } from '@/utils/auth'
import { useUserStoreHook } from '@/stores/user'
import { watch } from 'vue'

export function directives(app: App) {
  // 鉴权指令
  authDirective(app)
  // 权限指令
  permissionDirective(app)
}

/**
 * 页面按钮鉴权指令
 * @description v-auth="['role1', 'role2']"，基于用户角色进行权限控制
 */
function authDirective(app: App) {
  app.directive('auth', {
    mounted(el, binding) {
      checkAuth(el, binding)
    },
    updated(el, binding) {
      checkAuth(el, binding)
    }
  })
}

/**
 * 页面按钮权限指令
 * @description v-permission="['permission1', 'permission2']"，基于用户权限进行控制
 */
function permissionDirective(app: App) {
  app.directive('permission', {
    mounted(el, binding) {
      checkPermission(el, binding)
    },
    updated(el, binding) {
      checkPermission(el, binding)
    }
  })
}

function checkAuth(el: any, binding: DirectiveBinding) {
  const { value } = binding
  const userStore = useUserStoreHook()
  // 检查角色的函数
  const doAuthCheck = () => {
    const roles = userStore.roles
    if (value && value instanceof Array) {
      if (value.length > 0) {
        const authRoles = value
        // 如果角色数据还没加载（空数组），先不移除元素
        if (roles.length === 0) {
          console.log('角色数据还未加载，等待加载完成...')
          return false // 返回false表示还未完成检查
        }

        const hasAuth = roles.some((role: string) => {
          return authRoles.includes(role)
        })

        if (!hasAuth) {
          el.parentNode && el.parentNode.removeChild(el)
        }
        return true // 返回true表示检查完成
      }
    } else {
      console.error(`need roles! Like v-auth="['admin','editor']"`)
      return true
    }
    return true
  }

  // 首次检查
  const checkCompleted = doAuthCheck()

  // 如果首次检查未完成（角色数据未加载），则监听角色数据变化
  if (!checkCompleted) {
    const stopWatcher = watch(
      () => userStore.roles,
      (newRoles) => {
        if (newRoles && newRoles.length > 0) {
          console.log('角色数据已加载，重新检查权限')
          doAuthCheck()
          stopWatcher() // 停止监听
        }
      },
      { immediate: false }
    )
  }
}

function checkPermission(el: any, binding: DirectiveBinding) {
  const { value } = binding
  const userStore = useUserStoreHook()
  const plaid = getPlaid()

  // 检查权限的函数
  const doPermissionCheck = () => {
    const permissions = (plaid && (userStore.permission as any)[plaid]) || []
    if (value && value instanceof Array) {
      if (value.length > 0) {
        const permissionRoles = value
        // 如果权限数据还没加载（空数组且不是明确的空权限），先不移除元素
        if (permissions.length === 0 && plaid && !(userStore.permission as any)[plaid]) return false // 返回false表示还未完成检查
        const hasPermission = permissions.some((permission: string) => {
          return permissionRoles.includes(permission)
        })

        if (!hasPermission) {
          el.parentNode && el.parentNode.removeChild(el)
        }
        return true // 返回true表示检查完成
      }
    } else {
      console.error(`need permissions! Like v-permission="['admin','editor']"`)
      return true
    }
    return true
  }

  // 首次检查
  const checkCompleted = doPermissionCheck()

  // 如果首次检查未完成（权限数据未加载），则监听权限数据变化
  if (!checkCompleted && plaid) {
    const stopWatcher = watch(
      () => (userStore.permission as any)[plaid],
      (newPermissions) => {
        if (newPermissions && newPermissions.length >= 0) {
          console.log('权限数据已加载，重新检查权限')
          doPermissionCheck()
          stopWatcher() // 停止监听
        }
      },
      { immediate: false }
    )
  }
}
